<template>
  <div class="app-container">
    <!-- 查询表单 -->
    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
      <el-form-item label="绘本名称" prop="bookName">
        <el-input v-model="queryParams.bookName" placeholder="请输入绘本名称" clearable size="small" style="width: 240px" />
      </el-form-item>

      <el-form-item label="备注信息" prop="remarks">
        <el-input v-model="queryParams.remarks" placeholder="请输入备注信息" clearable size="small" style="width: 240px" />
      </el-form-item>

      <el-form-item>
        <el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 工具栏 -->
    <el-row :gutter="10" class="mb8" v-if="!selectMode">
      <el-col :span="1.5">
        <el-button plain type="primary" icon="el-icon-plus" size="mini" @click="handleAdd">
          新增
        </el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
    </el-row>

    <!-- 查询结果表格 -->
    <el-table v-loading="loading" :data="bookList" @selection-change="handleSelectionChange">
      <el-table-column v-if="selectMode" type="selection" />
      <el-table-column label="ID" align="center" prop="id" />
      <el-table-column label="绘本名称" align="center" prop="bookName" />
      <el-table-column label="备注信息" align="center" prop="remarks" />
      <el-table-column label="操作" align="center">
        <template slot-scope="scope">
          <el-button v-if="!selectMode" type="primary" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">修改</el-button>
          <el-button type="info" size="mini" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
          <el-button v-if="!selectMode" type="danger" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 确认选择按钮 -->
    <div style="margin-top: 10px; text-align: right;" v-if="selectMode">
      <el-button type="primary" @click="confirmSelection">确认选择</el-button>
    </div>

    <!-- 分页 -->
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 新增/修改/详情绘本对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="1800px" append-to-body :close-on-click-modal="false" @close="handleDialogClose" style="margin-top: 0">
      <el-form ref="form" :model="form" :rules="rules" label-width="120px" :disabled="viewMode">
        <el-form-item label="绘本名称" prop="bookName">
          <el-input v-model="form.bookName" placeholder="请输入绘本名称" />
        </el-form-item>

        <!-- PDF上传：仅新增时显示 -->
        <el-form-item label="上传PDF" v-if="isAddMode">
          <el-upload
            action=""
            :http-request="uploadPdf"
            :limit="1"
            accept="application/pdf"
            :before-remove="beforeRemovePdf"
          >
            <el-button type="primary" icon="el-icon-upload">上传PDF</el-button>
          </el-upload>
        </el-form-item>

        <!-- 拖拽图片 + 单词 + 录音 -->
        <draggable v-model="form.pageList" handle=".drag-handle" animation="200" :disabled="viewMode">
          <transition-group tag="div" class="pages-grid">
            <div v-for="(page, pIndex) in form.pageList" :key="pIndex" class="page-card">
              <div class="page-header">
                <div>
                  <span class="drag-handle" v-if="isAddMode">☰</span>
                  <strong>第 {{ pIndex + 1 }} 页</strong>
                </div>
                <el-button type="danger" icon="el-icon-delete" size="mini" @click="removePage(pIndex)" v-if="isAddMode && !viewMode">删除</el-button>
              </div>

              <div class="page-image">
                <img :src="imagePrefix + page.pictureBookPage" />
              </div>

              <div class="page-word">
                <span>单词：</span>
                <el-input v-model="page.pageText" placeholder="请输入单词" :disabled="viewMode" />
              </div>

              <div class="page-audio">
                <span>录音：</span>
                <el-button
                  type="primary"
                  icon="el-icon-microphone"
                  @click="startRecord(pIndex)"
                  :disabled="recordingIndex === pIndex || viewMode"
                >
                  {{ recordingIndex === pIndex ? '录音中...' : '开始录音' }}
                </el-button>
                <el-button
                  type="danger"
                  @click="stopRecord"
                  :disabled="recordingIndex !== pIndex || viewMode"
                >停止</el-button>
                <div v-if="page.vocabularyAudio">
                  <audio :src="imagePrefix + page.vocabularyAudio" controls></audio>
                  <el-button v-if="!viewMode" type="danger" size="mini" icon="el-icon-delete" @click="removeAudio(pIndex)">删除录音</el-button>
                </div>
              </div>
            </div>
          </transition-group>
        </draggable>
      </el-form>

      <div slot="footer" class="dialog-footer" v-if="!viewMode">
        <el-button type="primary" @click="submitForm">{{ isAddMode ? '保 存' : '更 新' }}</el-button>
        <el-button @click="cancel">关 闭</el-button>
      </div>
      <div slot="footer" class="dialog-footer" v-else>
        <el-button @click="cancel">关 闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getAllPictureBooks, addPictureBook, delMenu, updatePictureBook } from "@/api/class/storybookM";
import { uploadFilesByType } from "@/api/class/classSchedule";
import draggable from "vuedraggable";

export default {
  name: "storybookM",
  components: { draggable },
  props: {
    selectMode: { type: Boolean, default: false }
  },
  data() {
    return {
      loading: false,
      bookList: [],
      total: 0,
      showSearch: true,
      open: false,
      title: "",
      isAddMode: true,
      viewMode: false,
      selectedRows: [],
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        id: undefined,
        bookName: undefined,
        remarks: undefined,
      },
      form: {
        id: undefined,
        bookName: undefined,
        pageList: [],
        bookFile: undefined,
      },
      originalForm: null,
      mediaRecorder: null,
      audioChunks: [],
      currentWord: { pIndex: null },
      rules: {
        bookName: [{ required: true, message: "绘本名称不能为空", trigger: "blur" }],
      },
      imagePrefix: `${window.location.origin}/`,
      recordingIndex: null,
      savingInstance: null,
    };
  },
  created() {
    this.getList();
  },
  methods: {
    getList() {
      this.loading = true;
      getAllPictureBooks(this.queryParams).then((response) => {
        this.bookList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    handleSelectionChange(selection) {
      this.selectedRows = selection;
    },
    confirmSelection() {
      this.$emit('confirm', this.selectedRows);
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    handleAdd() {
      this.reset();
      this.$nextTick(() => {
        this.resetForm("form");
      });
      this.open = true;
      this.title = "新增绘本";
      this.isAddMode = true;
      this.viewMode = false;
      this.originalForm = null;
    },
    handleEdit(row) {
      this.reset();
      this.form = JSON.parse(JSON.stringify(row));
      this.originalForm = JSON.parse(JSON.stringify(row));
      this.open = true;
      this.title = "修改绘本";
      this.isAddMode = false;
      this.viewMode = false;
    },
    handleView(row) {
      this.reset();
      this.form = JSON.parse(JSON.stringify(row));
      this.originalForm = JSON.parse(JSON.stringify(row));
      this.open = true;
      this.title = "绘本详情";
      this.isAddMode = false;
      this.viewMode = true;
    },
    handleDialogClose() {
      if (!this.isAddMode && this.originalForm) {
        this.form = JSON.parse(JSON.stringify(this.originalForm));
      } else {
        this.reset();
      }
    },
    reset() {
      this.form = { id: undefined, bookName: undefined, pageList: [], bookFile: undefined };
      if (this.$refs.form) {
        this.$refs.form.resetFields();
      }
    },
    uploadPdf(param) {
      const formData = new FormData();
      formData.append("file", param.file);
      formData.append("fileType", "picture_book");
      this.$loading({ lock: true, text: "正在解析PDF，请稍候...", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)" });
      uploadFilesByType(formData, "picture_book").then((res) => {
        this.$loading().close();
        if (res && Array.isArray(res.data)) {
          this.form.pageList = res.data.map(url => ({ pageText: undefined, pictureBookPage: url, vocabularyAudio: undefined }));
          this.form.bookFile = res.fileName;
          if (param.file && param.file.name && !this.form.bookName) {
            const nameWithoutExt = param.file.name.replace(/\.[^/.]+$/, "");
            this.form.bookName = nameWithoutExt;
          }
          param.onSuccess(res);
        } else {
          param.onError();
        }
      }).catch(() => {
        this.$loading().close();
        param.onError();
      });
    },
    beforeRemovePdf(file, fileList) {
      return new Promise((resolve, reject) => {
        this.$confirm('确定要删除上传的PDF文件吗？删除后所有页面和录音都会被清空！', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.removePdf();
          resolve();
        }).catch(() => {
          reject();
        });
      });
    },
    removePdf() {
      this.form.pageList = [];
      this.form.bookFile = undefined;
    },
    removePage(pIndex) {
      this.form.pageList.splice(pIndex, 1);
    },
    removeAudio(pIndex) {
      this.$set(this.form.pageList[pIndex], 'vocabularyAudio', undefined);
    },
    handleDelete(id) {
      this.$confirm('确定要删除该绘本吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delMenu(id).then(() => {
          this.msgSuccess("删除成功");
          this.getList();
        });
      });
    },
    startRecord(pIndex) {
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
          this.mediaRecorder = new MediaRecorder(stream);
          this.audioChunks = [];
          this.currentWord = { pIndex };
          this.recordingIndex = pIndex;
          this.mediaRecorder.ondataavailable = e => this.audioChunks.push(e.data);
          this.mediaRecorder.onstop = () => {
            const blob = new Blob(this.audioChunks, { type: 'audio/mp3' });
            const formData = new FormData();
            formData.append("file", blob, `audio_${Date.now()}.mp3`);
            formData.append("fileType", "picture_book_page_audio");
            uploadFilesByType(formData, "picture_book_page_audio").then((res) => {
              if (res && res.fileName) {
                this.$set(this.form.pageList[this.currentWord.pIndex], 'vocabularyAudio', res.fileName);
              }
            });
            this.recordingIndex = null;
          };
          this.mediaRecorder.start();
        });
      } else {
        this.$message.error("浏览器不支持录音功能");
      }
    },
    stopRecord() {
      if (this.mediaRecorder) {
        this.mediaRecorder.stop();
      }
    },
    submitForm() {
      const payload = JSON.parse(JSON.stringify(this.form));
      payload.pageList = payload.pageList.map(p => ({
        pageText: p.pageText,
        pictureBookPage: p.pictureBookPage,
        vocabularyAudio: p.vocabularyAudio
      }));

      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.savingInstance = this.$loading({ lock: true, text: "正在保存，请稍候...", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)" });
          if (this.isAddMode) {
            addPictureBook(payload).then(() => {
              this.savingInstance.close();
              this.msgSuccess("保存成功");
              //this.open = false;
              this.getList();
            }).catch(() => {
              this.savingInstance.close();
              this.$message.error("保存失败，请重试");
            });
          } else {
            updatePictureBook(payload).then(() => {
              this.savingInstance.close();
              this.msgSuccess("更新成功");
              //this.open = false;
              this.getList();
            }).catch(() => {
              this.savingInstance.close();
              this.$message.error("更新失败，请重试");
            });
          }
        }
      });
    },
    cancel() {
      this.open = false;
      this.handleDialogClose();
    },
  },
};
</script>


<style scoped>
.recording-indicator {
  color: red;
  font-weight: bold;
  margin-left: 10px;
}

.pages-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.page-card {
  flex: 1 1 calc(50% - 16px);
  border: 1px solid #eee;
  padding: 10px;
  border-radius: 4px;
  box-sizing: border-box;
  max-width: calc(50% - 16px);
}

@media (min-width: 1600px) {
  .page-card {
    flex: 1 1 calc(33.333% - 16px);
    max-width: calc(33.333% - 16px);
  }
}

@media (max-width: 768px) {
  .page-card {
    flex: 1 1 100%;
    max-width: 100%;
  }
}

.page-header {
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.page-image img {
  width: 100%;
  height: 400px;
  object-fit: contain;
  border: 1px solid #ccc;
  background: #f9f9f9;
}

.page-word {
  margin: 10px 0;
}

.page-audio audio {
  margin-top: 10px;
  width: 100%;
}
</style>
